package dl.martinfowler.wrapper;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * Implementation of Martin Fowler Simple Date Precision Wrapper called MfDate
 * http://martinfowler.com/ap2/timePoint.html
 * 
 * @author Martin Fowler
 * @implementer Basanta Raj Onta
 */
public class MfDate {

	private GregorianCalendar _base;

	public MfDate(int year, int month, int day) {
		initialize(new GregorianCalendar(year, month - 1, day));
	}

	public MfDate(GregorianCalendar gregorianCalendar) {
		initialize(gregorianCalendar);
	}

	public MfDate(java.sql.Date sqlDate) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTimeInMillis(sqlDate.getTime());
		initialize(calendar);
	}

	private void initialize(GregorianCalendar gregorianCalendar) {
		_base = trimToDays(gregorianCalendar);
	}

	private GregorianCalendar trimToDays(GregorianCalendar gregorianCalendar) {
		GregorianCalendar calendar = gregorianCalendar;
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar;
	}

	public GregorianCalendar getCalendar() {
		return _base;
	}

	public Date getTime() {
		return _base.getTime();
	}

	public int getYear() {
		return _base.get(Calendar.YEAR);
	}

	public int getMonth() {
		return _base.get(Calendar.MONTH);
	}

	public int getDayOfMonth() {
		return _base.get(Calendar.DAY_OF_MONTH);
	}

	public boolean after(MfDate mfDate) {
		return getTime().after(mfDate.getTime());
	}

	public boolean before(MfDate mfDate) {
		return getTime().before(mfDate.getTime());
	}

	public int compareTo(Object dateObject) {
		MfDate otherDate = (MfDate) dateObject;
		return getTime().compareTo(otherDate.getTime());
	}

	public boolean equals(Object dateObject) {
		if (this == dateObject)
			return true;
		if (!(dateObject instanceof MfDate))
			return false;
		MfDate otherDate = (MfDate) dateObject;
		return (_base.equals(otherDate._base));
	}

	public MfDate addDays(int days) {
		return new MfDate(new GregorianCalendar(getYear(), getMonth(),
				getDayOfMonth() + days));
	}

	public MfDate minusDays(int days) {
		return addDays(-days);
	}

	public java.sql.Date toSqlDate() {
		return new java.sql.Date(_base.getTimeInMillis());
	}

}
